namespace GYLite {
	export class SeqLoader extends egret.EventDispatcher {
		private _loadInfo: LoadInfo;
		private _intervalId: number;
		private _isLoading: number;
		private _cancelLockTime: number;
		public data: any;
		private _laterFunc: Function;
		private _laterObject: any;
		public bytes: any;
		private _loaderFactory: LoaderFactory;
		public constructor() {
			super();
			let s = this;
			s._loadInfo = null;
			s._intervalId = -1;
			s._isLoading = 0;
			s._cancelLockTime = 0;
			s.data = null;
		}
		public set loadInfo(val) {
			let s = this;
			if (val == null) {
				s._isLoading = 0;
				if (s._cancelLockTime == 0)
					s.clearCallLater();
				s.data = null;
				s.bytes = null;
				s.release();			
			}
			s._loadInfo = val;
		}
		public get loadInfo() {
			return this._loadInfo;
		}
		public get isLoading() {
			return this._isLoading;
		}
		public set isLoading(val) {
			this._isLoading = val;
		}
		public loadBytes(bytes: ArrayBuffer): void {
			let s = this;
			if (GYLoader._disposed) return;
			var blob: Blob;
			var url: string;
			let global: any;
			global = window;
			s.bytes = bytes;
			if (s._loadInfo.type == LoadType.TYPE_IMAGE && global.createImageBitmap) 
			{
				if (s._loaderFactory)
					s._loaderFactory.dispose();
				s._loaderFactory = new LoaderFactory;
				blob = new Blob([bytes], { type: s._loadInfo.mimeType });
				s._loaderFactory.loadBitmap(blob, s.loadComp, s);
			}
			else {
				if ((GYLoader.supportBlobMP3 == 2 && s._loadInfo.mimeType == "audio/mp3") || (GYLoader.supportBlobWAV == 2 && s._loadInfo.mimeType == "audio/wav") || egret.nativeRender) {
					let str: string = egret.Base64Util.encode(bytes);
					url = "data:" + s._loadInfo.mimeType + ";base64," + str;
					// console.log("运行时("+egret.Capabilities.runtimeType+"):" + (s._loadInfo.path?s._loadInfo.path:(s._loadInfo.param?s._loadInfo.param.url:bytes.length)));
				}
				else {
					if (GYLite.GYLoader.miniGame) {
						url = GYLite.GYLoader.miniGame.env.USER_DATA_PATH + "/" + (++egret.$hashCount);
						GYLite.GYLoader.miniGame.getFileSystemManager().readFile(url, bytes, "binary");

					}
					else {
						blob = new Blob([bytes], { type: s._loadInfo.mimeType });
						url = URL.createObjectURL(blob);
					}
					// console.log("非运行时("+egret.Capabilities.runtimeType+"):" + (s._loadInfo.path?s._loadInfo.path:(s._loadInfo.param?s._loadInfo.param.url:bytes.length)));
				}
				s.release();
				s._loaderFactory = new LoaderFactory;
				s._loaderFactory.loadRes(url, s._loadInfo.type, s.loadComp, s);
			}

		}
		public load(url: string) {
			let s = this;
			if (GYLoader._disposed) return;
			s.release();
			s._loaderFactory = new LoaderFactory;
			s._loaderFactory.loadRes(url, s.loadInfo.type, s.loadComp, s);
		}
		public loadBitmap(blob: Blob): void {
			let s = this;
			if (GYLoader._disposed) return;
			window["createImageBitmap"](blob).then(s.loadBitmapComp.bind(s));
		}
		private loadBitmapComp(response: any): void {
			if (GYLoader._disposed) return;
			let s = this;
			s.data = new egret.BitmapData(response);
			s.data.source.src = s._loadInfo.path;
			s.dispatchEvent(new egret.Event(egret.Event.COMPLETE));
		}
		private loadComp(status: number): void {
			if (GYLoader._disposed) return;
			let s = this;
			if (status != 0 && status != 200) {
				s.loadError();
				return;
			}
			var url = s.data.url;
			if (url && url.indexOf("blob:") == 0) {
				var winURL = window["URL"] || window["webkitURL"];
				try {
					winURL.revokeObjectURL(s.data.src);
				}
				catch (e) {
					egret.$warn(1037);
				}
			}
			s.dispatchEvent(new egret.Event(egret.Event.COMPLETE));
		}
		private loadError(): void {
			if (GYLoader._disposed) return;
			this.dispatchEvent(new egret.IOErrorEvent(egret.IOErrorEvent.IO_ERROR));
		}
		/**由于连续加载时，上一个失败立即使用这个loader会产生加载中断的bug，所以进行延时处理*/
		public callLater(func: Function, thisObject: any, delay: number = 100) {
			let s = this;
			s._laterFunc = func;
			s._laterObject = thisObject; var url = s.data.url;
			if (url.indexOf("blob:") == 0) {
				var winURL = window["URL"] || window["webkitURL"];
				try {
					winURL.revokeObjectURL(s.data.src);
				}
				catch (e) {
					egret.$warn(1037);
				}
			}
			s._intervalId = setTimeout(s.laterCall.bind(s), delay);
		}
		private laterCall(): void {
			let s = this;
			if (s._laterFunc != null)
				s._laterFunc.call(s._laterObject, s);
		}
		/**清理延时*/
		public clearCallLater() {
			let s = this;
			if (s._intervalId > -1) {
				clearInterval(s._intervalId);
				s._intervalId = -1;
			}
		}
		public get cancelLockTime() {
			let s = this;
			return s._cancelLockTime;
		}

		public set cancelLockTime(value) {
			let s = this;
			s._cancelLockTime = value;
		}
		public breakLock() {
			let s = this;
			s._cancelLockTime = 0;
		}
		private release():void
		{
			let s = this;
			if(s._loaderFactory)
			{
				s._loaderFactory.dispose();
            	s._loaderFactory = null;
			}			
		}
	}
}